package com.irdstudio.efp.esb.api.rest.hj;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Objects;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.irdstudio.basic.framework.core.constant.BaseConstant;
import com.irdstudio.basic.framework.core.constant.EsbRetCodeStandard;
import com.irdstudio.basic.framework.core.exception.ESBException;
import com.irdstudio.basic.framework.core.util.DateTool;
import com.irdstudio.basic.framework.core.util.TimeUtil;
import com.irdstudio.basic.framework.core.util.TraceUtil;
import com.irdstudio.efp.console.service.facade.PubSysInfoService;
import com.irdstudio.efp.esb.api.common.EsbRespServiceBeanCreator;
import com.irdstudio.efp.esb.common.constant.EsbBizEnums;
import com.irdstudio.efp.esb.common.constant.EsbSysHeadEnums;
import com.irdstudio.efp.esb.common.server.req.EsbReqServiceBean;
import com.irdstudio.efp.esb.common.server.resp.EsbRespServiceBean;
import com.irdstudio.efp.esb.service.bo.req.hj.ReqChgOpenDayNoticeBean;
import com.irdstudio.efp.esb.service.bo.resp.hj.RespChgOpenDayNoticeBean;

/**
 * 服务名称 ：50120001(日切通知)<br>
 * 服务场景名称：01(日切同步) <br>
 * 服务描述：用于日切通知<br>
 * 服务场景描述：该接口由互金核心日切后调用，网贷同步日切日期 <br>
 * 
 * @author ludayong
 * @since 2019年1月11日 下午2:14:13
 * @version 1.0
 */

@RestController
@RequestMapping("/esb")
public class ChgOpenDayNoticeController {

	private static Logger logger = LoggerFactory.getLogger(ChgOpenDayNoticeController.class);

	@Autowired
	@Qualifier("pubSysInfoService")
	private PubSysInfoService pubSysInfoService;// 营业日期

	/**
	 * 获取ESB请求对象，校验 ESB请求系统头和请求应用头对象
	 * 
	 * @param request
	 *            请求对象集合
	 * @return
	 * @author ludayong
	 * @since 2019年1月20日 下午1:28:08
	 * @version 1.0
	 */
	@ModelAttribute("esbReqServiceBean")
	public EsbReqServiceBean getReqEsbHeadBean(HttpServletRequest request) {
		logger.info("校验 ESB请求系统头和请求应用头对象!");
		EsbReqServiceBean esbReqServiceBean = (EsbReqServiceBean) request.getAttribute("esbReqServiceBean");
		return esbReqServiceBean;
	}

	/**
	 * 获取ESB请求对象，校验 ESB请求体对象
	 * 
	 * @param request
	 *            请求对象集合
	 * @return
	 * @author ludayong
	 * @since 2019年1月20日 下午1:31:14
	 * @version 1.0
	 */
	@ModelAttribute("reqChgOpenDayNoticeBean")
	public ReqChgOpenDayNoticeBean getReqEsbBodyBean(HttpServletRequest request) {
		logger.info("校验 ESB请求体对象！");
		String esbReqBody = (String) request.getAttribute("esbReqBody");
		return JSONObject.parseObject(esbReqBody, ReqChgOpenDayNoticeBean.class);
	}

	/**
	 * 
	 * 日切通知处理
	 * 
	 * @param esbReqBodyBean
	 * @return
	 * @throws ESBException
	 * @throws Exception
	 * @author ludayong
	 * @since 2019年1月11日 下午2:15:53
	 * @version 1.0
	 */
	@PostMapping("/SERVICE_50120001_01")
	public EsbRespServiceBean doRecv(@Validated @ModelAttribute("esbReqServiceBean") EsbReqServiceBean esbReqServiceBean, BindingResult br1,
			@Validated @ModelAttribute("reqChgOpenDayNoticeBean") ReqChgOpenDayNoticeBean reqChgOpenDayNoticeBean, BindingResult br2,
			Exception exception) {
		try {
			if (Objects.nonNull(exception)) {
				throw exception;
			}
			// 2.日切通知请求参数
			logger.info("日切通知报文[" + JSONObject.toJSONString(reqChgOpenDayNoticeBean) + "]");
			// 接口字段校验
			String opnDt = reqChgOpenDayNoticeBean.getOpnDt();
			String lstOpnDt = reqChgOpenDayNoticeBean.getLstOpnDt();

			boolean checkOpnDtRes = DateTool.isDate(opnDt);// 营业日期
			boolean checkLstOpnDtRes = DateTool.isDate(lstOpnDt);// 上一个营业日期
			boolean checkDtRes = false;// 校验营业日期比上一个营业日期大一天
			boolean checkCurDtRes = false;// 校验网贷系统营业日期与上一营业日期

			DateFormat format = new SimpleDateFormat("yyyy-MM-dd");

			try {
				format.parse(opnDt);
			} catch (Exception e) {
				logger.error("***********营业日期格式[yyyy-MM-dd]不正确，请检查！**************");
				return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean,
						JSON.toJSONString(buildRespChgOpenDayNoticeBean(EsbRetCodeStandard.OTHERS_EXCEPTION.getValue(), "营业日期格式[yyyy-MM-dd]不正确，请检查！")),
						EsbSysHeadEnums.RetStEnum.SUCCESS.getCode(), EsbRetCodeStandard.OTHERS_EXCEPTION.getValue(), "营业日期格式[yyyy-MM-dd]不正确，请检查！");
			}
			try {
				format.parse(lstOpnDt);
			} catch (Exception e) {
				logger.error("***********上一营业日期格式[yyyy-MM-dd]不正确，请检查！**************");
				return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean,
						JSON.toJSONString(buildRespChgOpenDayNoticeBean(EsbRetCodeStandard.OTHERS_EXCEPTION.getValue(), "上一营业日期格式[yyyy-MM-dd]不正确，请检查！")),
						EsbSysHeadEnums.RetStEnum.SUCCESS.getCode(), EsbRetCodeStandard.OTHERS_EXCEPTION.getValue(), "上一营业日期格式[yyyy-MM-dd]不正确，请检查！");
			}

			if (!checkOpnDtRes) {// 校验营业日期格式
				logger.error("***********上一营业日期格式[yyyy-MM-dd]不正确，请检查！**************");
				return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean,
						JSON.toJSONString(buildRespChgOpenDayNoticeBean(EsbRetCodeStandard.OTHERS_EXCEPTION.getValue(), "营业日期格式[yyyy-MM-dd]不正确，请检查！")),
						EsbSysHeadEnums.RetStEnum.SUCCESS.getCode(), EsbRetCodeStandard.OTHERS_EXCEPTION.getValue(), "营业日期格式[yyyy-MM-dd]不正确，请检查！");
			}

			if (!checkLstOpnDtRes) {// 校验上一营业日期格式
				logger.error("***********上一营业日期格式[yyyy-MM-dd]不正确，请检查！**************");
				return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean,
						JSON.toJSONString(buildRespChgOpenDayNoticeBean(EsbRetCodeStandard.OTHERS_EXCEPTION.getValue(), "上一营业日期格式[yyyy-MM-dd]不正确，请检查！")),
						EsbSysHeadEnums.RetStEnum.SUCCESS.getCode(), EsbRetCodeStandard.OTHERS_EXCEPTION.getValue(), "上一营业日期格式[yyyy-MM-dd]不正确，请检查！");
			}

			if (checkOpnDtRes && checkLstOpnDtRes) {// 校验营业日期比上一个营业日期大一天
				String cpLstOpnDt = TimeUtil.addDay(opnDt, -1);
				if (!lstOpnDt.equals(cpLstOpnDt)) {
					logger.error("***********营业日期应要比上一营业日期大一天，请检查！**************");
					return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean,
							JSON.toJSONString(buildRespChgOpenDayNoticeBean(EsbRetCodeStandard.OTHERS_EXCEPTION.getValue(), "营业日期应要比上一营业日期大一天，请检查！")),
							EsbSysHeadEnums.RetStEnum.SUCCESS.getCode(), EsbRetCodeStandard.OTHERS_EXCEPTION.getValue(), "营业日期应要比上一营业日期大一天，请检查！");
				} else {
					checkDtRes = true;
				}
			}

			if (checkOpnDtRes && checkLstOpnDtRes && checkDtRes) {
				String curDate = pubSysInfoService.getOpenday(BaseConstant.SYS_ID_1001);// 网贷系统营业日期
				String cpCurDate = TimeUtil.addDay(opnDt, -1);
				if (!cpCurDate.equals(curDate)) {// 校验网贷系统营业日期与上一营业日期
					logger.error("***********上一营业日期[LstOpnDt]与网贷系统营业日期不一致！**************");
					return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean,
							JSON.toJSONString(buildRespChgOpenDayNoticeBean(EsbRetCodeStandard.OTHERS_EXCEPTION.getValue(), "上一营业日期[LstOpnDt]与网贷系统营业日期不一致！")),
							EsbSysHeadEnums.RetStEnum.SUCCESS.getCode(), EsbRetCodeStandard.OTHERS_EXCEPTION.getValue(), "上一营业日期[LstOpnDt]与网贷系统营业日期不一致！");
				} else {
					checkCurDtRes = true;
				}
			}

			// 如果一致则更新网贷的营业日期，不一致则返回错误信息
			if (checkOpnDtRes && checkLstOpnDtRes && checkDtRes && checkCurDtRes) {
				try {
					pubSysInfoService.chgOpenDay(BaseConstant.SYS_ID_1001, opnDt, lstOpnDt);// 开始日切
					return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean,
							JSON.toJSONString(buildRespChgOpenDayNoticeBean(EsbBizEnums.RetCodeEnum.SUCCESS.getVALUE(), EsbBizEnums.RetCodeMsg.SUCCESS_MSG.VALUE)),
							EsbSysHeadEnums.RetStEnum.SUCCESS.getCode(), EsbBizEnums.RetCodeEnum.SUCCESS.getVALUE(), EsbBizEnums.RetCodeMsg.SUCCESS_MSG.VALUE);
				} catch (Exception e) {
					// 组装返回报文
					logger.error("***********日切通知处理调用失败**************");
					return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean,
							JSON.toJSONString(buildRespChgOpenDayNoticeBean(EsbRetCodeStandard.OTHERS_EXCEPTION.getValue(), e.getMessage())),
							EsbSysHeadEnums.RetStEnum.FAILURE.getCode(), EsbRetCodeStandard.OTHERS_EXCEPTION.getValue(), e.getMessage());
				}
			}
			return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean,
					JSON.toJSONString(buildRespChgOpenDayNoticeBean(EsbBizEnums.RetCodeEnum.SUCCESS.getVALUE(), EsbBizEnums.RetCodeMsg.SUCCESS_MSG.VALUE)),
					EsbSysHeadEnums.RetStEnum.SUCCESS.getCode(), EsbBizEnums.RetCodeEnum.SUCCESS.getVALUE(),EsbBizEnums.RetCodeMsg.SUCCESS_MSG.VALUE);
		} catch (Exception e) {
			logger.error("***********日切通知处理调用失败**************");
			e.printStackTrace();
			return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean,
					JSON.toJSONString(buildRespChgOpenDayNoticeBean(EsbRetCodeStandard.OTHERS_EXCEPTION.getValue(), e.getMessage())),
					EsbSysHeadEnums.RetStEnum.FAILURE.getCode(), EsbRetCodeStandard.OTHERS_EXCEPTION.getValue(), e.getMessage());
		} finally {
			TraceUtil.clear();
		}
		
	}

	/**
	 * 日切通知接口的返回对象
	 * 
	 * @param retStCd
	 *            返回状态码
	 * @param rtnMsg
	 *            返回信息
	 * @return
	 * @author ludayong
	 * @since 2019年1月20日 下午1:59:46
	 * @version 1.0
	 */
	private static RespChgOpenDayNoticeBean buildRespChgOpenDayNoticeBean(String retStCd, String rtnMsg) {
		RespChgOpenDayNoticeBean respBean = new RespChgOpenDayNoticeBean();
		respBean.setRetCd(retStCd);
		respBean.setRetMsg(rtnMsg);
		return respBean;
	}
}
